package de.slothsoft.wasbinich.android;

import static de.slothsoft.wasbinich.android.util.ViewUtil.setText;

import java.util.Locale;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import de.slothsoft.wasbinich.android.util.ActivityUtil;
import de.slothsoft.wasbinich.android.util.ImageUtil;
import de.slothsoft.wasbinich.android.util.ViewUtil;
import de.slothsoft.wasbinich.core.FullPicture;
import de.slothsoft.wasbinich.core.WasBinIch;
import de.slothsoft.wasbinich.core.database.Database;
import de.slothsoft.wasbinich.core.util.PictureUtil;

/**
 * A fragment representing a single Picture detail screen. This fragment is
 * either contained in a {@link PictureListActivity} in two-pane mode (on
 * tablets) or a {@link PictureDetailActivity} on handsets.
 */
public class PictureDetailFragment extends Fragment implements OnClickListener {

    public static final String ARG_PICTURE_ID = "picture_id";//$NON-NLS-1$
    public static final String ARG_NEW_PICTURE_URL = "new_picture_url";//$NON-NLS-1$

    private View rootView;
    private FullPicture picture;
    private FullPicture originalPicture;

    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	if (getArguments().containsKey(ARG_NEW_PICTURE_URL)) {
	    this.picture = createNewPicture(getArguments().getString(ARG_NEW_PICTURE_URL));
	} else if (getArguments().containsKey(ARG_PICTURE_ID)) {
	    final long id = getArguments().getLong(ARG_PICTURE_ID);
	    if (id != -1) {
		getActivity().setProgressBarIndeterminateVisibility(true);
		new Thread(new Runnable() {
		    @Override
		    public void run() {
			try {
			    setPicture(Database.getInstance().getManagerBean().getPicture(id));
			    if (getRootView() != null) {
				getActivity().runOnUiThread(new Runnable() {
				    @Override
				    public void run() {
					updateViewsFromPicture();
					getActivity().setProgressBarIndeterminateVisibility(false);
				    }
				});
			    }
			} catch (Exception exception) {
			    getActivity().runOnUiThread(new Runnable() {
				@Override
				public void run() {
				    getActivity().setProgressBarIndeterminateVisibility(false);
				}
			    });
			    ActivityUtil.handleFatalException(getActivity(), exception);
			}
		    }
		}).start();
	    }
	}
    }

    private FullPicture createNewPicture(String url) {
	FullPicture result = new FullPicture();
	result.section = parseImage(Uri.parse(url));
	return result;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
	this.rootView = inflater.inflate(R.layout.fragment_picture_detail, container, false);
	if (this.picture != null) {
	    updateViewsFromPicture();
	}
	hookListeners();
	return this.rootView;
    }

    private void hookListeners() {
	((ImageView) this.rootView.findViewById(R.id.picture_detail_field_big_picture)).setOnClickListener(this);
	((ImageView) this.rootView.findViewById(R.id.picture_detail_field_section)).setOnClickListener(this);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
	int itemId = item.getItemId();
	if (itemId == R.id.picture_detail_save) {
	    performSave();
	    return true;
	} else if (itemId == R.id.picture_detail_delete) {
	    performDelete();
	    return true;
	}
	return super.onOptionsItemSelected(item);
    }

    protected void performSave() {
	updatePictureFromViews();
	if (!isValid())
	    return;

	getActivity().setProgressBarIndeterminateVisibility(true);
	new Thread(new Runnable() {
	    @Override
	    public void run() {
		try {
		    FullPicture picture = getPicture();
		    if (picture.id == null) {
			setPicture(Database.getInstance().getManagerBean().createPicture(picture));
		    } else {
			FullPicture differences = PictureUtil.getDifferences(getOriginalPicture(), picture);
			if (differences != null) {
			    setPicture(Database.getInstance().getManagerBean().updatePicture(picture));
			}
		    }
		    getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
			    Toast.makeText(getActivity(), R.string.picture_detail_save_complete, Toast.LENGTH_LONG)
				    .show();
			    updateViewsFromPicture();
			    getActivity().setProgressBarIndeterminateVisibility(false);
			}
		    });
		} catch (Exception exception) {
		    getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
			    getActivity().setProgressBarIndeterminateVisibility(false);
			}
		    });
		    ActivityUtil.handleException(getActivity(), exception);
		}
	    }
	}).start();
    }

    private boolean isValid() {
	if (!hasCorrectAnswer()) {
	    showMessage(R.string.picture_detail_must_have_correct_answer);
	    return false;
	}
	return true;
    }

    private boolean hasCorrectAnswer() {
	for (Locale locale : WasBinIch.SUPPORTED_LANGUAGES) {
	    String correctAnswers = this.picture.getCorrectAnswers(locale);
	    if (correctAnswers != null && !correctAnswers.equals("")) //$NON-NLS-1$
		return true;
	}
	return false;
    }

    private void performDelete() {
	getActivity().setProgressBarIndeterminateVisibility(true);
	new Thread(new Runnable() {
	    @Override
	    public void run() {
		try {
		    FullPicture picture = getPicture();
		    if (picture.id != null) {
			Database.getInstance().getManagerBean().deletePicture(picture.id);
		    }
		    getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
			    getActivity().setProgressBarIndeterminateVisibility(false);
			    closeFragment();
			}

		    });
		} catch (Exception exception) {
		    getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
			    getActivity().setProgressBarIndeterminateVisibility(false);
			}
		    });
		    ActivityUtil.handleFatalException(getActivity(), exception);
		}
	    }
	}).start();
    }

    protected void closeFragment() {
	getActivity().startActivity(new Intent(getActivity(), PictureListActivity.class));
    }

    private void updatePictureFromViews() {
	this.picture.correctAnswers_de = ViewUtil.getText(this.rootView
		.findViewById(R.id.picture_detail_field_correct_answers_de));
	this.picture.correctAnswers_en = ViewUtil.getText(this.rootView
		.findViewById(R.id.picture_detail_field_correct_answers_en));
	this.picture.description_en = ViewUtil.getText(this.rootView
		.findViewById(R.id.picture_detail_field_description_en));
	this.picture.description_de = ViewUtil.getText(this.rootView
		.findViewById(R.id.picture_detail_field_description_de));
    }

    private void updateViewsFromPicture() {
	setText(this.rootView.findViewById(R.id.picture_detail_field_correct_answers_de),
		this.picture.correctAnswers_de);
	setText(this.rootView.findViewById(R.id.picture_detail_field_correct_answers_en),
		this.picture.correctAnswers_en);
	setText(this.rootView.findViewById(R.id.picture_detail_field_description_en), this.picture.description_en);
	setText(this.rootView.findViewById(R.id.picture_detail_field_description_de), this.picture.description_de);
	setImageToView(this.rootView, this.picture.section, R.id.picture_detail_field_section);
	setImageToView(this.rootView, this.picture.bigPicture, R.id.picture_detail_field_big_picture);
    }

    private void setImageToView(View rootView, String imageData, int viewId) {
	ImageView imageSectionView = (ImageView) rootView.findViewById(viewId);
	Bitmap bitmap = ImageUtil.convertStringToBitmap(imageData);
	if (bitmap != null) {
	    imageSectionView.setImageBitmap(bitmap);
	}
    }

    @Override
    public void onClick(View v) {
	updatePictureFromViews();

	Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
	galleryintent.setType("image/*"); //$NON-NLS-1$

	Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

	Intent chooser = new Intent(Intent.ACTION_CHOOSER);
	chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
	chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.picture_detail_select_picture));

	Intent[] intentArray = { cameraIntent };
	chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

	if (v.getId() == R.id.picture_detail_field_section) {
	    startActivityForResult(chooser, ActionCodes.SELECT_SECTION_IMAGE);
	} else if (v.getId() == R.id.picture_detail_field_big_picture) {
	    startActivityForResult(chooser, ActionCodes.SELECT_BIG_IMAGE);
	}
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
	super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
	if (resultCode != Activity.RESULT_OK)
	    return;
	switch (requestCode) {
	case ActionCodes.SELECT_BIG_IMAGE:
	    this.picture.bigPicture = parseImage(imageReturnedIntent.getData());
	    break;
	case ActionCodes.SELECT_SECTION_IMAGE:
	    this.picture.section = parseImage(imageReturnedIntent.getData());
	    break;
	}
	updateViewsFromPicture();
    }

    private String parseImage(Uri selectedImage) {
	try {
	    Bitmap bitmap = ImageUtil.decodeUrlToSmallerImage(getActivity(), selectedImage, WasBinIch.PICTURE_SIZE);
	    return ImageUtil.convertBitmapToString(bitmap);
	} catch (Exception e) {
	    showMessage(e.getMessage());
	    return null;
	}
    }

    private void showMessage(final String message) {
	Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
    }

    private void showMessage(final int messageId) {
	Toast.makeText(getActivity(), messageId, Toast.LENGTH_LONG).show();
    }

    public void setPicture(FullPicture picture) {
	this.picture = picture;
	this.originalPicture = picture.clone();
    }

    public FullPicture getPicture() {
	return this.picture;
    }

    public FullPicture getOriginalPicture() {
	return this.originalPicture;
    }

    public View getRootView() {
	return this.rootView;
    }

}
